/*
**    Copyright (C) 2003-2011 Institute for Systems Biology
**                            Seattle, Washington, USA.
**
**    This library is free software; you can redistribute it and/or
**    modify it under the terms of the GNU Lesser General Public
**    License as published by the Free Software Foundation; either
**    version 3 of the License, or (at your option) any later version.
**
**    This library is distributed in the hope that it will be useful,
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
**    Lesser General Public License for more details.
**
**    You should have received a copy of the GNU Lesser General Public
**    License along with this library; if not, write to the Free Software
**    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
*/

package org.systemsbiology.util;


/**
 * Specialization of Pair that requires Comparable member types.
 * Implements a lexicographic compareTo.
 * @author anorberg
 *
 * @param <F> First type.
 * @param <S> Second type.
 */
public class SortablePair<F extends Comparable<F>, S extends Comparable<S>>
		extends Pair<F, S> implements Comparable<Pair<F, S>> {

	public SortablePair(F first, S second){
		super(first, second);
	}

    /**
     * A copy constructor that will take any Pair, not just a SortablePair. This is only possible
     * if the Pair types are convertible to the types for this SortablePair, which requires the Pair types
     * to also be sortable. The copy of the contents is shallow.
     * @param originalPair Pair to copy.
     */
    public SortablePair(Pair<? extends F, ? extends S> originalPair){
        super(originalPair.first, originalPair.second);
    }
	
	@Override
	public int compareTo(Pair<F, S> other) {
		if(first == null){
			if(other.first == null){
				if(second == null){
					if(other.second == null){
						return 0;
					}
					return -1;
				} else {
					if(other.second == null){
						return 1;
					} else {
						return second.compareTo(other.second);
					}
				}
			} else {
				//nothing before something
				return -1;
			}
		}
		int r = first.compareTo(other.first);
		if(r == 0){
			if(second == null){
				if(other.second == null){
					return 0;
				} else {
					return -1;
				}
			} else {
				if(other.second == null){
					return 1;
				}else{
					return second.compareTo(other.second);
				}
			}
		}
		return r;
	}

}
